<template>
  <div class="table-template">
    <slot name="tableHeader">
      <z-form v-if="formList.length > 0" ref="ruleForm" :model="formModel" autocomplete="off" class="list-form">
        <z-row wrap :gutter="20">
          <!-- eslint-disable-next-line vue/no-v-for-template-key -->
          <template v-for="item in formArr1" :key="item.currentKey">
            <!-- v-if="item.isShow == '1'" -->
            <z-col
              :span="item.layoutVO.span"
              :offset="item.layoutVO.offset"
              :pull="item.layoutVO.pull"
              :push="item.layoutVO.push"
              :xs="item.layoutVO.xs"
              :sm="item.layoutVO.sm"
              :md="item.layoutVO.md"
              :lg="item.layoutVO.lg"
              :xl="item.layoutVO.xl"
              :xxl="item.layoutVO.xxl"
              :xxxl="item.layoutVO.xxxl"
            >
              <slot v-if="$slots[item.field]" :name="item.field" :formModel="formModel" />
              <component
                :is="formRender(item)"
                v-else
                v-model:form-model="formModel"
                :basic-property="item"
                :form-model="formModel"
                :form-list="formArr1"
              />
            </z-col>
          </template>
          <!-- eslint-disable-next-line vue/no-v-for-template-key -->
          <template v-for="item in formArr2" :key="item.currentKey">
            <z-col
              v-if="advanced"
              :span="item.layoutVO.span"
              :offset="item.layoutVO.offset"
              :pull="item.layoutVO.pull"
              :push="item.layoutVO.push"
              :xs="item.layoutVO.xs"
              :sm="item.layoutVO.sm"
              :md="item.layoutVO.md"
              :lg="item.layoutVO.lg"
              :xl="item.layoutVO.xl"
              :xxl="item.layoutVO.xxl"
              :xxxl="item.layoutVO.xxxl"
            >
              <slot v-if="$slots[item.field]" :name="item.field" :formModel="formModel" />
              <component
                :is="formRender(item)"
                v-else
                v-model:form-model="formModel"
                :basic-property="item"
                :form-model="formModel"
                :form-list="formArr2"
              />
            </z-col>
          </template>
        </z-row>
        <z-form-item style="margin-bottom: 0; text-align: right">
          <a
            v-if="formList && formList.length > 6"
            @click="advanced = !advanced"
          >
            <span style="margin-right: 8px">{{ advanced ? "收起" : "展开" }}</span>
            <down-outlined v-show="!advanced" />
            <up-outlined v-show="advanced" />
          </a>
          <slot name="tableFooter">
            <z-button style="margin: 0 12px 0 26px" type="primary" @click="searchBtn">
              查询
            </z-button>
            <z-button @click="resetForm">
              重置
            </z-button>
          </slot>
        </z-form-item>
      </z-form>
    </slot>
    <div class="table-content">
      <slot name="tableBtns">
        <z-button type="primary" style="margin-bottom: 20px" @click="addNode">
          新增
        </z-button>
      </slot>
      <z-table
        :data-source="dataSource"
        :columns="columns"
        :pagination="false"
        :scroll="{ y: tableHeight }"
      >
        <template #headerCell="{ column }">
          <template v-if="column.isOrder == '1'">
            <span>
              {{ column.title }}
            </span>
            <span class="table-icon">
              <z-tooltip placement="topLeft">
                <template #title>
                  <span>点击升序</span>
                </template>
                <caret-up-outlined @click="upSort(column)" />
              </z-tooltip>
              <z-tooltip placement="topLeft">
                <template #title>
                  <span>点击降序</span>
                </template>
                <caret-down-outlined @click="downSort(column)" />
              </z-tooltip>
            </span>
          </template>
        </template>
        <template #bodyCell="{ column, text, record, index }">
          <slot v-if="$slots.operateBtn" name="operateBtn" :column="column" :text="text" :record="record" :index="index" />
          <template v-if="column?.dataIndex === 'operate' && !$slots.operateBtn">
            <z-button type="link" @click="editNode(record)">
              编辑
            </z-button>
            <z-button type="link" style="margin: 0 16px" @click="detailNode(record)">
              详情
            </z-button>
            <z-button type="link" danger @click="deleteNode(record)">
              删除
            </z-button>
          </template>
        </template>
      </z-table>
      <z-pagination
        v-if="pageOpt.total > 0"
        v-model:current="pageOpt.page"
        v-model:page-size="pageOpt.pageSize"
        class="pagination"
        :total="pageOpt.total"
        show-quick-jumper
        :show-total="(total) => `共 ${pageOpt.total} 条`"
        @change="pageChange"
      />
    </div>
  </div>
</template>
<script>
import {
  defineComponent,
  ref,
  onMounted,
  getCurrentInstance,
  computed,
  reactive,
  nextTick,
  toRefs
} from 'vue'

import InputItem from './components/input.vue'
import SelectItem from './components/select.vue'

import DateItem from './components/date.vue'
import TreeSelectItem from './components/treeSelectItem.vue'
import TimeItem from './components/time.vue'

import tableOpt from '../zMixins/table'
import formInfo from '../../api/renderForm/index.js'
import { message, Modal } from '../index.js'
import { useStore } from 'vuex'

export default defineComponent({
  name: 'ZTableTemplate',
  components: {
    InputItem,
    SelectItem,
    DateItem,
    TreeSelectItem,
    TimeItem
  },
  mixins: [tableOpt],
  props: {
    formKey: {
      type: String,
      default: undefined
    },
    // 是否调用默认表格接口
    isGetData: {
      type: Boolean,
      default: undefined
    },
    // 是否调用删除接口
    isDelData: {
      type: Boolean,
      default: undefined
    },
    // 是否显示第一列序号列
    isShowNum: {
      type: Boolean,
      default: undefined
    }
  },
  setup(props, context) {
    const store = useStore()
    const { ctx } = getCurrentInstance()

    // 是否调用表格接口
    const isGetData = computed(() => props.isGetData)
    // 是否调用删除接口
    const isDelData = computed(() => props.isDelData)

    let dataSource = ref([])
    let columns = ref([])

    // 收起展开
    const state = reactive({
      advanced: false,
      formArr1: [],
      formArr2: []
    })

    // 排序
    let queryOrderList = ref([])

    let pageOpt = ref({
      page: 1,
      pageSize: 10,
      total: 0
    })

    let formList = ref([])

    // 判断是否为JSON
    const IsJsonString = (str) => {
      try {
        JSON.parse(str)
      } catch (e) {
        return false
      }
      return true
    }
    // 列表详情
    const getFormDetail = () => {
      let params = {
        appId: 'ZRAR',
        formKey: props.formKey
      }
      formInfo.getListMessage(params).then((res) => {
        if (res.code === 1) {
          if (res?.data?.listSearchVOList) {
            let data = res.data.listSearchVOList
            formList.value = data.map((item) => {
              for (let [key, value] of Object.entries(item)) {
                if (
                  IsJsonString(value) &&
                  Array.isArray(JSON.parse(value)) === true
                ) {
                  item[key] = JSON.parse(value)
                }
              }
              return item
            })

            // 组件   添加操作中的显隐存值---vuex
            let isShowArr = []
            formList.value.forEach(i => {
              if (i?.relaFields?.length > 0 && i?.relaFields?.filter(j => j.operateType === '3').length > 0) {
                isShowArr.push({
                  field: i.field,
                  relaFields: i?.relaFields?.filter(j => j.operateType === '3')
                })
              }
            })
            store.commit('formMake/UPDATE_ISSHOWARR', isShowArr)

            // 是否显示第一列序号列
            if (props?.isShowNum) {
              columns.value.push({
                title: '序号',
                width: 70,
                customRender: (e) => `${e.index + 1}`,
                align: 'center'
              })
            }
            res.data.listShowVOList.map(item => {
              // if (item.isShow === '1') {
              columns.value.push({
                title: item.headText,
                dataIndex: item.field,
                ellipsis: true,
                width: item.headWidth,
                currentKey: item.currentKey,
                isOrder: item.isOrder,
                // eslint-disable-next-line no-eval
                customRender: eval(item.personFunction)
              })
              // }
            })
            columns.value.push({
              title: '操作',
              dataIndex: 'operate',
              width: 200
            })
            nextTick(() => {
              context.emit('viewDone')
            })
          }
          state.formArr1 = formList.value.slice(0, 6)
          state.formArr2 = formList.value.slice(6, formList.value.length)
          if (isGetData.value) {
            getTableInfo()
          }
        }
      })
    }

    // 查询
    const searchBtn = () => {
      pageOpt.value.page = 1
      pageOpt.value.pageSize = 10
      if (isGetData.value) {
        getTableInfo()
      }
      context.emit('searchBtn')
    }

    // 表格数据
    const getTableInfo = () => {
      // 防止查询条件的数据对象受影响
      let obj = Object.assign({}, formModel.value)
      for (let i in obj) {
        if (Array.isArray(obj[i]) === true) {
          obj[i] = (obj[i]).join(',')
        }
      }
      // 数据转换
      let queryConditionList = []
      for (let [key, value] of Object.entries(obj)) {
        queryConditionList.push({
          attrName: key,
          value: value
        })
      }
      let map = {
        appId: 'ZRAR',
        listFormKey: props.formKey,
        queryConditionList: queryConditionList,
        queryOrderList: queryOrderList.value
      }
      formInfo.getTableData(map, pageOpt.value.page, pageOpt.value.pageSize).then(res => {
        if (res.code === 1) {
          dataSource.value = res.data.list ? res.data.list : []
          pageOpt.value.total = res.data.total
        }
      })
    }

    // 挂载
    onMounted(() => {
      getFormDetail()
    })

    // 查询数据对象
    const getForm = () => {
      const model = {}
      formList.value.forEach((list) => {
        if (list.attrType === '2' || list.attrType === '4') {
          Object.assign(model, {
            [list.field]: list.value || undefined
          })
        } else {
          Object.assign(model, {
            [list.field]: list.value || ''
          })
        }
      })
      return model
    }

    const formModel = computed(() => reactive(getForm()))

    // 组件渲染
    const formRender = (element) => {
      let componentId = ''
      switch (element.attrType) {
        case '1':
          componentId = 'InputItem'
          break
        case '2':
          componentId = 'SelectItem'
          break
        case '3':
          componentId = 'DateItem'
          break
        case '4':
          componentId = 'TreeSelectItem'
          break
        case '5':
          componentId = 'TimeItem'
          break
      }
      return componentId
    }

    // 表格高度自适应
    const tableHeight = computed(() => {
      return ctx.tableContentHeight - 232 // 减去查询表单高度得到table scoll y
    })

    const ruleForm = ref(null)

    // 重置
    const resetForm = () => {
      pageOpt.value.page = 1
      pageOpt.value.pageSize = 10
      ruleForm.value.resetFields()
      queryOrderList.value = []
      if (isGetData.value) {
        getTableInfo()
      }
      context.emit('resetForm')
    }

    // 添加
    const addNode = () => {
      context.emit('addNode')
    }
    // 编辑
    const editNode = (row) => {
      context.emit('editNode', row)
    }
    // 详情
    const detailNode = (row) => {
      context.emit('detailNode', row)
    }
    // 删除
    const deleteNode = (row) => {
      if (isDelData.value) {
        Modal.confirm({
          title: '是否进行删除操作?',
          zIndex: '3000',
          centered: true,
          okText: '确定',
          cancelText: '取消',
          onOk() {
            let params = {
              appId: 'ZRAR',
              formKey: props.formKey,
              value: row.id
            }
            formInfo
              .delTableData(params)
              .then((res) => {
                if (res.code === 1) {
                  message.success(res.message)
                  if (isGetData.value) {
                    if (dataSource.value.length === 1) {
                      if (pageOpt.value.page > 1) {
                        pageOpt.value.page = Number(pageOpt.value.page) - 1
                      }
                    }
                    getTableInfo()
                  }
                }
              })
          }
        })
      }
      context.emit('deleteNode', row)
    }

    // 切换页码事件
    const pageChange = () => {
      if (isGetData.value) {
        getTableInfo()
      }
      context.emit('pageChange', pageOpt.value)
    }

    // 表格升序
    const upSort = (column) => {
      queryOrderList.value = [
        {
          attrName: column.dataIndex,
          orderType: '1'
        }
      ]
      if (isGetData.value) {
        getTableInfo()
      }
      context.emit('upSort', column)
    }
    // 表格降序
    const downSort = (column) => {
      queryOrderList.value = [
        {
          attrName: column.dataIndex,
          orderType: '2'
        }
      ]
      if (isGetData.value) {
        getTableInfo()
      }
      context.emit('downSort', column)
    }

    // 取消排序
    const cancelSort = (column) => {
      queryOrderList.value = []
      if (isGetData.value) {
        getTableInfo()
      }
      context.emit('cancelSort', column)
    }

    return {
      ruleForm,
      formList,
      dataSource,
      columns,
      formModel,
      formRender,
      tableHeight,
      resetForm,
      pageOpt,
      getTableInfo,
      searchBtn,
      addNode,
      editNode,
      detailNode,
      deleteNode,
      pageChange,
      upSort,
      downSort,
      cancelSort,
      ...toRefs(state)
    }
  }
})
</script>

<style lang="less">
.table-template {
  display: flex;
  flex-direction: column;
  height: 100%;
  // 排序icon
  .table-icon {
    float: right;
    display: flex;
    flex-direction: column;
  }
  // 上边表单控件
  .list-form {
    background: #ffffff;
    border-radius: 4px;
    padding: 20px;
  }
  // 下边表格控件
  .table-content {
    flex: 1;
    margin-top: 16px;
    height: calc(~"100% - 192px");
    background: #ffffff;
    border-radius: 4px;
    padding: 20px;
    position: relative;
  }
  .pagination {
    position: absolute;
    bottom: 20px;
    right: 20px;
  }
}
</style>
